package com.gitee.wsl.mathematics.geometry.d2.rect.ext

import com.gitee.wsl.mathematics.coordinate.d2.Coordinate2
import com.gitee.wsl.mathematics.geometry.d2.line.ext.projectedPoint
import com.gitee.wsl.mathematics.geometry.d2.rect.RectangleShape2d
import com.gitee.wsl.mathematics.vector.ext.minus


fun<N:Number> RectangleShape2d<N, *,*>.normalVectorAt(p: Coordinate2<N, *>): Coordinate2<N, *> {
    val pp = projectedPoint(p)
    val x = when (pp.x) {
        left -> -1.0
        right -> +1.0
        else -> 0.0
    } +zero
    val y = when (pp.y) {
        top -> -1.0
        bottom -> +1.0
        else -> 0.0
    } +zero
    return createPoint2(x, y).normalized as Coordinate2<N, *>
}

fun<N:Number,V:Coordinate2<N, V>> RectangleShape2d<N, V, *>.projectedPoint(p: Coordinate2<N, *>): Coordinate2<N, *> {
    val p0 = createLine(topLeft, topRight).projectedPoint(p)
    val p1 = createLine(topRight, bottomRight).projectedPoint(p)
    val p2 = createLine(bottomRight, bottomLeft).projectedPoint(p)
    val p3 = createLine(bottomLeft, topLeft).projectedPoint(p)
    val d0 = (p0 - p).squaredLength
    val d1 = (p1 - p).squaredLength
    val d2 = (p2 - p).squaredLength
    val d3 = (p3 - p).squaredLength
    val dmin = min(d0, d1, d2, d3)
    return when (dmin) {
        d0 -> p0
        d1 -> p1
        d2 -> p2
        d3 -> p3
        else -> p0
    }
}